package com.xdl.common.jwt;

import cn.hutool.json.JSONUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import com.xdl.common.constants.CommonConstants;
import com.nimbusds.jose.JWSObject;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * jwt生成&解析token
 *
 * @author iron guo
 * @since 2022.01.05
 */
@Slf4j
public class JWTHelper {

    /**
     * 秘钥
     */
    public static final String SECRET_KEY = "isanlife";

    /**
     * 签发人
     */
    private static final String ISSUER = "isanlife";


    public static final long EXPIRE_TIME = 90;

    /**
     * 生成token
     *
     * @param jwtInfo
     * @param expire
     * @return
     */
    public static String generateToken(IJWTInfo jwtInfo, int expire) {
        Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
        String token = JWT.create().withIssuer(ISSUER).withIssuedAt(new Date())
                //过期时间
                .withExpiresAt(buildExpirationDate(expire))
                //保存身份标识
                .withClaim(CommonConstants.JWT_KEY_NAME, jwtInfo.getUserName())
                .withClaim(CommonConstants.JWT_KEY_USER_ID, jwtInfo.getUserId())
                .withClaim(CommonConstants.JWT_KEY_PHONE, jwtInfo.getPhone())
                .withClaim(CommonConstants.JWT_KEY_OPEN_ID, jwtInfo.getOpenId())
                .sign(algorithm);
        return token;
    }


    /**
     * 获取token中的用户信息
     *
     * @param token
     * @return
     * @throws Exception
     */
    public static IJWTInfo getInfoFromToken(String token) throws Exception {
        JWSObject jwsObject = JWSObject.parse(token);
        String userStr = jwsObject.getPayload().toString();
        JWTInfo info = JSONUtil.toBean(userStr, JWTInfo.class);
        return info;
    }

    public static void main(String[] args) {

        //创建验证对象
        Verification verification = JWT.require(Algorithm.HMAC256("isanlife"));//签名
        JWTVerifier jwtVerifier = verification.build();
        DecodedJWT verify = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvcGVuSWQiOiJva3NQeTRzQWJPOGZ6a3pRel8yQmtlN0ZDaTRrIiwiaXNzIjoiaXNhbmxpZmUiLCJleHAiOjE2NjQwMDE3NjQsInVzZXJOYW1lIjoieGRsXzM5MDU2Nzg1NjU1MzQ2MzgwOCIsImlhdCI6MTY1NjIyNTc2NCwidXNlcklkIjoiMzkwNTY3ODU2NTQ5MjY5NTA0In0.F6FkCU57660iyowL-NttyulMmM58K78Od-tZHSaZ6sc");

        Claim userId = verify.getClaim("userId");
        Claim username = verify.getClaim("userName");
        System.out.println(userId.asString());
        System.out.println(username.asString());
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("过期时间：" + sdf.format(verify.getExpiresAt()));

    }

    /**
     * 验证token
     */
    public static boolean verify(String token) {
        try {
            //算法
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build();
            verifier.verify(token);
            return true;
        } catch (Exception ex) {
            log.info("Token校验不通过:{}", token);
        }
        return false;
    }


    private static Date buildExpirationDate(int expire) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, expire);
        return calendar.getTime();
    }

}
